<?php

namespace App\Services;

use App\Models\User;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

/**
 * 权限管理服务
 * 实现功能导向的权限控制系统
 */
class PermissionService
{
    /**
     * 缓存键前缀
     */
    private const CACHE_PREFIX = 'permissions:';

    /**
     * 缓存过期时间（秒）
     */
    private const CACHE_TTL = 3600; // 1小时

    /**
     * 权限配置
     */
    private array $permissionsConfig;

    public function __construct()
    {
        $this->permissionsConfig = config('permissions', []);
    }

    /**
     * 获取用户权限列表
     */
    public function getUserPermissions(User $user): array
    {
        $cacheKey = self::CACHE_PREFIX . 'user:' . $user->id;

        return Cache::remember($cacheKey, self::CACHE_TTL, function () use ($user) {
            $permissions = [];

            // 获取用户角色
            try {
                $roles = $user->getActiveRoles()->get();

                foreach ($roles as $role) {
                    $rolePermissions = $this->getRolePermissions($role->code);
                    $permissions = array_merge($permissions, $rolePermissions);
                }
            } catch (\Exception $e) {
                Log::error('获取用户角色失败', [
                    'user_id' => $user->id,
                    'error' => $e->getMessage()
                ]);
            }

            // 去重
            return array_unique($permissions);
        });
    }

    /**
     * 获取角色权限列表
     */
    public function getRolePermissions(string $roleName): array
    {
        $cacheKey = self::CACHE_PREFIX . 'role:' . $roleName;

        return Cache::remember($cacheKey, self::CACHE_TTL, function () use ($roleName) {
            // 首先尝试从配置文件获取
            $roleConfig = $this->permissionsConfig['roles'][$roleName] ?? [];

            if (!empty($roleConfig)) {
                $permissions = $roleConfig['permissions'] ?? [];

                // 处理通配符权限
                if (in_array('*', $permissions)) {
                    return $this->getAllPermissions();
                }

                return $permissions;
            }

            // 如果配置文件中没有，则尝试从数据库获取
            try {
                $role = \App\Models\Role::where('code', $roleName)->first();

                if ($role && $role->permissions) {
                    $permissions = $role->permissions;

                    // 处理通配符权限
                    if (in_array('*', $permissions)) {
                        return $this->getAllPermissions();
                    }

                    return $permissions;
                }
            } catch (\Exception $e) {
                Log::error('获取数据库角色权限失败', [
                    'role_name' => $roleName,
                    'error' => $e->getMessage()
                ]);
            }

            return [];
        });
    }

    /**
     * 检查用户是否有指定权限
     */
    public function hasPermission(User $user, string $permission): bool
    {
        // 超级管理员绕过权限检查
        if ($this->isSuperAdmin($user)) {
            return true;
        }

        $userPermissions = $this->getUserPermissions($user);

        return in_array($permission, $userPermissions);
    }

    /**
     * 检查用户是否有任意一个权限
     */
    public function hasAnyPermission(User $user, array $permissions): bool
    {
        // 超级管理员绕过权限检查
        if ($this->isSuperAdmin($user)) {
            return true;
        }

        $userPermissions = $this->getUserPermissions($user);

        return !empty(array_intersect($permissions, $userPermissions));
    }

    /**
     * 检查用户是否有所有权限
     */
    public function hasAllPermissions(User $user, array $permissions): bool
    {
        // 超级管理员绕过权限检查
        if ($this->isSuperAdmin($user)) {
            return true;
        }

        $userPermissions = $this->getUserPermissions($user);

        return empty(array_diff($permissions, $userPermissions));
    }

    /**
     * 检查用户是否有访问路由的权限
     */
    public function canAccessRoute(User $user, string $method, string $uri): bool
    {
        // 超级管理员绕过权限检查
        if ($this->isSuperAdmin($user)) {
            return true;
        }

        $requiredPermission = $this->getRoutePermission($method, $uri);

        if (!$requiredPermission) {
            // 如果路由未配置权限，根据配置决定是否允许访问
            return !($this->permissionsConfig['validation']['strict_mode'] ?? false);
        }

        return $this->hasPermission($user, $requiredPermission);
    }

    /**
     * 获取路由所需的权限
     */
    public function getRoutePermission(string $method, string $uri): ?string
    {
        $cacheKey = self::CACHE_PREFIX . 'route:' . $method . ':' . $uri;

        return Cache::remember($cacheKey, self::CACHE_TTL, function () use ($method, $uri) {
            $modules = $this->permissionsConfig['modules'] ?? [];

            foreach ($modules as $module) {
                $permissions = $module['permissions'] ?? [];

                foreach ($permissions as $permissionKey => $permissionConfig) {
                    $routes = $permissionConfig['routes'] ?? [];

                    foreach ($routes as $routePattern) {
                        if ($this->matchRoute($routePattern, $method . ' ' . $uri)) {
                            return $permissionKey;
                        }
                    }
                }
            }

            return null;
        });
    }

    /**
     * 匹配路由模式
     */
    private function matchRoute(string $pattern, string $request): bool
    {
        // 将Laravel风格的路由模式转换为正则表达式
        $pattern = preg_replace('/\{[^}]+\}/', '[^/]+', $pattern);
        $pattern = str_replace('/', '\/', $pattern);
        $pattern = '/^' . $pattern . '$/';

        return preg_match($pattern, $request) === 1;
    }

    /**
     * 获取所有权限列表
     */
    public function getAllPermissions(): array
    {
        $cacheKey = self::CACHE_PREFIX . 'all_permissions';

        return Cache::remember($cacheKey, self::CACHE_TTL, function () {
            $permissions = [];
            $modules = $this->permissionsConfig['modules'] ?? [];

            foreach ($modules as $module) {
                $modulePermissions = $module['permissions'] ?? [];
                $permissions = array_merge($permissions, array_keys($modulePermissions));
            }

            return array_unique($permissions);
        });
    }

    /**
     * 获取权限配置
     */
    public function getPermissionConfig(string $permission): ?array
    {
        $modules = $this->permissionsConfig['modules'] ?? [];

        foreach ($modules as $module) {
            $permissions = $module['permissions'] ?? [];

            if (isset($permissions[$permission])) {
                return $permissions[$permission];
            }
        }

        return null;
    }

    /**
     * 获取模块配置
     */
    public function getModuleConfig(string $module): ?array
    {
        return $this->permissionsConfig['modules'][$module] ?? null;
    }

    /**
     * 获取所有模块
     */
    public function getAllModules(): array
    {
        return $this->permissionsConfig['modules'] ?? [];
    }

    /**
     * 获取所有角色
     */
    public function getAllRoles(): array
    {
        return $this->permissionsConfig['roles'] ?? [];
    }

    /**
     * 检查用户是否为超级管理员
     */
    public function isSuperAdmin(User $user): bool
    {
        if (!($this->permissionsConfig['validation']['super_admin_bypass'] ?? false)) {
            return false;
        }

        $roles = $user->roles ?? [];
        foreach ($roles as $role) {
            if ($role->name === 'super_admin') {
                return true;
            }
        }

        return false;
    }

    /**
     * 清除权限缓存
     */
    public function clearCache(string $type = null, string $identifier = null): void
    {
        if ($type === 'user' && $identifier) {
            Cache::forget(self::CACHE_PREFIX . 'user:' . $identifier);
        } elseif ($type === 'role' && $identifier) {
            Cache::forget(self::CACHE_PREFIX . 'role:' . $identifier);
        } elseif ($type === 'route' && $identifier) {
            Cache::forget(self::CACHE_PREFIX . 'route:' . $identifier);
        } else {
            // 清除所有权限缓存
            Cache::forget(self::CACHE_PREFIX . 'all_permissions');

            $keys = Cache::get('permission_cache_keys', []);
            foreach ($keys as $key) {
                Cache::forget($key);
            }

            Cache::forget('permission_cache_keys');
        }

        Log::info('Permission cache cleared', ['type' => $type, 'identifier' => $identifier]);
    }

    /**
     * 刷新权限缓存
     */
    public function refreshCache(): void
    {
        $this->clearCache();

        // 重新生成缓存
        $this->getAllPermissions();

        Log::info('Permission cache refreshed');
    }

    /**
     * 获取用户可访问的菜单
     */
    public function getUserMenus(User $user): array
    {
        $cacheKey = self::CACHE_PREFIX . 'menus:' . $user->id;

        return Cache::remember($cacheKey, self::CACHE_TTL, function () use ($user) {
            // 这里应该根据用户的权限和菜单配置生成菜单树
            // 暂时返回空数组，具体实现需要根据前端菜单配置
            return [];
        });
    }
}
